package com.zhucai.credit.service.impl.transactional;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.annotation.Resource;

import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.domain.Sort.Order;
import org.springframework.stereotype.Service;

import com.zhucai.credit.bean.CreditApplication;
import com.zhucai.credit.bean.CreditProduct;
import com.zhucai.credit.bean.EntCrProd;
import com.zhucai.credit.bean.FinanceAccountOperation;
import com.zhucai.credit.common.CommonEnums.CrAprovalStatus;
import com.zhucai.credit.common.CommonEnums.CrProdType;
import com.zhucai.credit.common.CommonEnums.CrProdstatus;
import com.zhucai.credit.common.CommonEnums.EnCrStatus;
import com.zhucai.credit.common.CommonEnums.EntType;
import com.zhucai.credit.common.CommonEnums.OperType;
import com.zhucai.credit.common.CommonEnums.ZhuCaiProdType;
import com.zhucai.credit.common.HelpConstant;
import com.zhucai.credit.common.MyPage;
import com.zhucai.credit.form.CreditApplicationForm;
import com.zhucai.credit.model.CreditApplicationEntity;
import com.zhucai.credit.model.CreditProductEntity;
import com.zhucai.credit.model.EntAccountEntity;
import com.zhucai.credit.model.EntCrProdEntity;
import com.zhucai.credit.model.FinanceAccountOperationEntity;
import com.zhucai.credit.model.OperRecordEntity;
import com.zhucai.credit.monitor.service.INotificationService;
import com.zhucai.credit.repository.CreditApplicationRepository;
import com.zhucai.credit.repository.CreditProductRepository;
import com.zhucai.credit.repository.CreditRecordRepository;
import com.zhucai.credit.repository.CreditRecordTimeRepository;
import com.zhucai.credit.repository.EntAccountRepository;
import com.zhucai.credit.repository.EntCertificateRepository;
import com.zhucai.credit.repository.EntCrProdEntityRepository;
import com.zhucai.credit.repository.FinanceAccountOperationRepository;
import com.zhucai.credit.repository.FinanceDrawRepository;
import com.zhucai.credit.repository.FinanceRepaymentRepository;
import com.zhucai.credit.repository.OperRecordRepository;
import com.zhucai.credit.repository.PaymentOrderItemRepository;
import com.zhucai.credit.service.CrProdSerice;
import com.zhucai.credit.service.impl.email.EmailServiceUtil;
import com.zhucai.credit.service.impl.excel.ExcelExportUtil;
import com.zhucai.credit.service.impl.problem.ProblemSericeImpl;
import com.zhucai.credit.utils.SqlResultUtil;

/**
 * 融资机构相关接口实现
 * 
 * @author hsg
 * @version 2018年8月8日
 *
 */
@Service("crProdSericeImpl")
@com.alibaba.dubbo.config.annotation.Service(version = "1.0.0")
public class CrProdSericeImpl implements CrProdSerice {
	private static final Logger logger = LoggerFactory.getLogger(CrProdSericeImpl.class);
	@Autowired
	private FinanceDrawRepository financeDrawRepository;
	@Autowired
	private FinanceAccountOperationRepository financeAccountOperationRepository;
	@Autowired
	private FinanceRepaymentRepository financeRepaymentRepository;
	@Autowired
	private CreditRecordTimeRepository creditRecordTimeRepository;
	@Autowired
	private ProblemSericeImpl problemSericeImpl;
	@Autowired
	private CreditUserServiceUtil creditUserServiceUtil;
	@Autowired
	private PaymentOrderItemRepository paymentOrderItemRepository;
	@Autowired
	private CreditProductRepository creditProductRepository;
	@Autowired
	private EntAccountRepository entAccountRepository;
	@Autowired
	private EntCertificateRepository entCertificateRepository;
	@Autowired
	private OperRecordRepository operRecordRepository;
	@Autowired
	private CreditRecordRepository creditRecordRepository;
	@Autowired
	private EntCrProdEntityRepository entCrProdEntityRepository;
	@Autowired
	private CreditApplicationRepository creditApplicationRepository;
	@Autowired
	private ExcelExportUtil excelExportUtil;
	@Autowired
	private EmailServiceUtil emailServiceUtil;
	@Resource(name = "EMAIL")
	private INotificationService emailINotificationService;
	@Override
	public CreditProduct findBankInfo(Long bankId) {
		// TODO Auto-generated method stub
		CreditProductEntity cpe = creditProductRepository.findOne(bankId);
		if (cpe == null) {
			return null;
		}
		CreditProduct cp = new CreditProduct();
		BeanUtils.copyProperties(cpe, cp);
		return cp;
	}

	@Override
	public CreditProduct findProdByType(String bankType) {
		// TODO Auto-generated method stub
		CreditProductEntity cpe = creditProductRepository.findByCrProdTypeAndStatusNot(bankType, HelpConstant.Status.delete);
		if (cpe == null) {
			return null;
		}
		CreditProduct cp = new CreditProduct();
		BeanUtils.copyProperties(cpe, cp);
		return cp;

	}

	/**
	 * 变更融资机构银行
	 * 
	 * @author hsg
	 * @version 2018年8月7日
	 * @param payId
	 * @param tid
	 * @param bankId
	 * @return
	 */
	@Override
	public Boolean changeBankProd(Long payId, Long tid, Long bankId) {
		logger.info("### 变更融资机构银行 start payId={},tid = {},bankId={}", payId, tid, bankId);
		if (payId == null && tid == null) {
			throw new RuntimeException("变更融资机构银行失败");
		}
		Integer coo = creditRecordRepository.updateBankProd(payId, tid, bankId);
		if (coo != 1) {
			logger.error("### 变更融资机构银行 更新异常，coo={}", coo);
		}
		return true;
	}

	/**
	 * 查询融资银行集合
	 * 
	 * @author hsg
	 * @version 2018年7月11日
	 * @return
	 */
	@Override
	public List<CreditProduct> getBankList(Long purEntId, Long supEntId) {
		// TODO Auto-generated method stub
		List<CreditProductEntity> findByStatusNot = creditProductRepository.findByStatusNot(HelpConstant.Status.delete);
		EntAccountEntity purAccount = null;
		EntAccountEntity supAccount = null;
		if (purEntId != null) {
			purAccount = entAccountRepository.findByStatusNotAndEnterpriseIdAndEntType(HelpConstant.Status.delete, purEntId, EntType.PURCHASER.toString());
			supAccount = entAccountRepository.findByStatusNotAndEnterpriseIdAndEntType(HelpConstant.Status.delete, supEntId, EntType.SUPPLIER.toString());
		}
		FinanceAccountOperationEntity findByAccIdAndStatusNot = null;
		if (purAccount != null && supAccount != null) {

			findByAccIdAndStatusNot = financeAccountOperationRepository.findByAccPurIdAndAccSupIdAndStatusNot(purAccount.getTid(), supAccount.getTid(), HelpConstant.Status.delete);
		}

		List<CreditProduct> rsList = new ArrayList<CreditProduct>();
		for (CreditProductEntity creditProductEntity : findByStatusNot) {
			CreditProduct creditProduct = new CreditProduct();
			BeanUtils.copyProperties(creditProductEntity, creditProduct);
			// 查询核心企业和对应银行机构的授信e度
			if (purAccount != null) {
				EntCrProdEntity entCrProdEntity = entCrProdEntityRepository.findByEnAccIdAndStatusNotAndCrPrTypeId(purAccount.getTid(), HelpConstant.Status.delete,
						creditProductEntity.getTid());
				if (entCrProdEntity != null) {
					// 查询核心企业是否开通此银行的筑保通
					creditProduct.setProdStatus(entCrProdEntity.getEnCrStatus());
					creditProduct.setPurCreditLine(entCrProdEntity.getPurCreditLine() == null ? BigDecimal.ZERO : entCrProdEntity.getPurCreditLine());
					BigDecimal purSurplusCreditLine = getPurSurplusCreditLine(purAccount.getTid());
					creditProduct.setPurSurplusCreditLine(purSurplusCreditLine);
				} else {
					creditProduct.setPurCreditLine(BigDecimal.ZERO);
					creditProduct.setPurSurplusCreditLine(BigDecimal.ZERO);
					creditProduct.setProdStatus(EnCrStatus.APPROVALING.toString());
				}

			}
			// 判断是否是核心企业选择的默认银行
			if (findByAccIdAndStatusNot != null && findByAccIdAndStatusNot.getBankId().equals(creditProduct.getTid())) {
				creditProduct.setDefaultBankClass("active");
			}
			if (supAccount != null && purAccount != null) {
				// 查询核心企业和供应此银行是否在合作中
				Integer count = creditApplicationRepository.findCoopStatus(creditProductEntity.getTid(), supAccount.getTid(), purAccount.getTid());
				if (count > 0) {
					creditProduct.setCrProdstatus(CrProdstatus.IN_COOPERATION.toString());
				} else {
					creditProduct.setCrProdstatus(CrProdstatus.WAIT_APPROVAL.toString());

				}
			}
			rsList.add(creditProduct);
		}

		return rsList;
	}

	// 获取核心企业的剩余授信额度
	public BigDecimal getPurSurplusCreditLine(Long accId) {

		return BigDecimal.ZERO;
	}

	/**
	 * 获取默认银行信息
	 * 
	 * @author hsg
	 * @version 2018年7月11日
	 * @param enterpriseId
	 * @param entType
	 * @return
	 */
	@Override
	public CreditProduct getFinanceAccountBankInfo(Long purEntId, Long supEntId) {
		EntAccountEntity purAccount = entAccountRepository.findByStatusNotAndEnterpriseIdAndEntType(HelpConstant.Status.delete, purEntId, EntType.PURCHASER.toString());
		EntAccountEntity supAccount = entAccountRepository.findByStatusNotAndEnterpriseIdAndEntType(HelpConstant.Status.delete, supEntId, EntType.SUPPLIER.toString());
		// TODO Auto-generated method stub
		CreditProductEntity creditProductEntity = creditProductRepository.findFinanceAccountBankInfo(purAccount.getTid(), supAccount.getTid());
		if (creditProductEntity == null) {
			return null;
		}
		CreditProduct creditProduct = new CreditProduct();
		BeanUtils.copyProperties(creditProductEntity, creditProduct);
		// 判断此核心和企业和供应商是否在合作中
		CreditApplicationEntity cae = creditApplicationRepository.findCoopInfo(HelpConstant.Status.delete, supAccount.getTid(), purAccount.getTid(),
				CrAprovalStatus.BANK_SUCCESS.toString(), creditProduct.getTid());
		if (cae != null) {
			creditProduct.setCrProdstatus(CrProdstatus.IN_COOPERATION.toString());
		} else {
			creditProduct.setCrProdstatus(CrProdstatus.EXPIRED.toString());
		}
		return creditProduct;
	}

	/**
	 * 添加默认银行
	 * 
	 * @author hsg
	 * @version 2018年7月12日
	 * @param purEntId
	 * @param supEntId
	 * @param bankId
	 * @return
	 */
	@Override
	public CreditProduct addDefaultBank(Long purEntId, Long supEntId, Long bankId) {
		// TODO Auto-generated method stub
		EntAccountEntity purAccount = entAccountRepository.findByStatusNotAndEnterpriseIdAndEntType(HelpConstant.Status.delete, purEntId, EntType.PURCHASER.toString());
		EntAccountEntity supAccount = entAccountRepository.findByStatusNotAndEnterpriseIdAndEntType(HelpConstant.Status.delete, supEntId, EntType.SUPPLIER.toString());
		FinanceAccountOperationEntity findByAccIdAndStatusNot = financeAccountOperationRepository.findByAccPurIdAndAccSupIdAndStatusNot(purAccount.getTid(), supAccount.getTid(),
				HelpConstant.Status.delete);
		if (findByAccIdAndStatusNot == null) {
			findByAccIdAndStatusNot = new FinanceAccountOperationEntity();
			findByAccIdAndStatusNot.setAccPurId(purAccount.getTid());
			findByAccIdAndStatusNot.setAccSupId(supAccount.getTid());
			findByAccIdAndStatusNot.setBankId(bankId);
			findByAccIdAndStatusNot.setCreDate(new Date());
			financeAccountOperationRepository.save(findByAccIdAndStatusNot);
		} else {
			financeAccountOperationRepository.updateBankId(bankId, purAccount.getTid(), supAccount.getTid());
		}
		CreditProduct cp = new CreditProduct();
		CreditProductEntity findOne = creditProductRepository.findOne(bankId);
		if (findOne != null) {
			BeanUtils.copyProperties(findOne, cp);
		}
		return cp;
	}

	/**
	 * 删除默认银行
	 * 
	 * @author hsg
	 * @version 2018年7月12日
	 * @param purchaserId
	 * @param supplierId
	 * @return
	 */
	@Override
	public Integer delDefaultBank(Long purEntId, Long supEntId) {
		EntAccountEntity purAccount = entAccountRepository.findByStatusNotAndEnterpriseIdAndEntType(HelpConstant.Status.delete, purEntId, EntType.PURCHASER.toString());
		EntAccountEntity supAccount = entAccountRepository.findByStatusNotAndEnterpriseIdAndEntType(HelpConstant.Status.delete, supEntId, EntType.SUPPLIER.toString());
		FinanceAccountOperationEntity findByAccIdAndStatusNot = financeAccountOperationRepository.findByAccPurIdAndAccSupIdAndStatusNot(purAccount.getTid(), supAccount.getTid(),
				HelpConstant.Status.delete);
		Integer coo = 0;
		if (findByAccIdAndStatusNot != null) {
			coo = financeAccountOperationRepository.delByPurIdAndSupId(purAccount.getTid(), supAccount.getTid());
		}
		return coo;
	}

	/**
	 * 获取金融账号银行辅助信息
	 * 
	 * @author hsg
	 * @version 2018年7月11日
	 * @param enterpriseId
	 * @param entType
	 * @return
	 */
	@Override
	public FinanceAccountOperation getFinanceAccountOperation(Long purEntId, Long supEntId) {
		EntAccountEntity purAccount = entAccountRepository.findByStatusNotAndEnterpriseIdAndEntType(HelpConstant.Status.delete, purEntId, EntType.PURCHASER.toString());
		EntAccountEntity supAccount = entAccountRepository.findByStatusNotAndEnterpriseIdAndEntType(HelpConstant.Status.delete, supEntId, EntType.SUPPLIER.toString());
		// TODO Auto-generated method stub
		FinanceAccountOperationEntity findByAccIdAndStatusNot = financeAccountOperationRepository.findByAccPurIdAndAccSupIdAndStatusNot(purAccount.getTid(), supAccount.getTid(),
				HelpConstant.Status.delete);
		if (findByAccIdAndStatusNot != null) {
			FinanceAccountOperation FinanceAccountOperation = new FinanceAccountOperation();
			BeanUtils.copyProperties(findByAccIdAndStatusNot, FinanceAccountOperation);
			return FinanceAccountOperation;
		} else {
			return null;
		}

	}

	private List<String> getCrApproveEnums(String bankType) {
		List<String> coopStatusList = new ArrayList<String>();

		if (bankType.equals(CrProdType.E_POINT.toString())) {
			coopStatusList.add(CrAprovalStatus.APPLY.toString());
			coopStatusList.add(CrAprovalStatus.BANK_ACCOUNT_REJECT.toString());
			coopStatusList.add(CrAprovalStatus.BANK_ACCOUNT_SUCCESS.toString());
			coopStatusList.add(CrAprovalStatus.BANK_AUDIT.toString());
			coopStatusList.add(CrAprovalStatus.DATA_REVIEW.toString());
			coopStatusList.add(CrAprovalStatus.PUR_CONFIRM_SUCCESS.toString());
			coopStatusList.add(CrAprovalStatus.PUR_REJECT.toString());
		} else if (bankType.equals(CrProdType.ICBC_R_E_J.toString())) {
			coopStatusList.add(CrAprovalStatus.ICBC_APPROVE_FINAL.toString());
//			coopStatusList.add(CrAprovalStatus.ICBC_APPROVE_FIRST.toString());
			coopStatusList.add(CrAprovalStatus.ICBC_APPROVE_TWO.toString());
//			coopStatusList.add(CrAprovalStatus.ICBC_FIRST_REJECT.toString());
			coopStatusList.add(CrAprovalStatus.ICBC_HISTROY_INFO.toString());
			coopStatusList.add(CrAprovalStatus.ICBC_REJECT_PUR.toString());
			coopStatusList.add(CrAprovalStatus.ICBC_STOP_PUR.toString());
			coopStatusList.add(CrAprovalStatus.ICBC_WAIT_CONFIRM_PUR.toString());
		}
		coopStatusList.add(CrAprovalStatus.OVER.toString());
		coopStatusList.add(CrAprovalStatus.BANK_SUCCESS.toString());
		return coopStatusList;

	}

	/**
	 * 查询合作商家信息
	 * 
	 * @version 2018年8月9日
	 * @param ca
	 * @param pageable
	 * @return
	 */
	@Override
	public CreditApplicationForm findcoopBusList(CreditApplication ca, Pageable pageable) {
		logger.info("### 查询合作商家信息 start ca = {}", ca.toString());
		EntAccountEntity entAcc = entAccountRepository.findByStatusNotAndEnterpriseIdAndEntType(HelpConstant.Status.delete, ca.getEnterpriseId(), ca.getEntType());
		if (entAcc == null) {
			return null;
		}
		
		// 根据融资机构类型查询tid
		CreditProductEntity cpeInfo = creditProductRepository.findByCrProdTypeAndStatusNot(ca.getCrProdType(), HelpConstant.Status.delete);

		// 封装资质申请审核状态集合
		List<String> coopStatusList = new ArrayList<String>();
		if ("ALL".equals(ca.getCrAprovalStatus())) {
			coopStatusList = getCrApproveEnums(cpeInfo.getCrProdType());
		} else {
			coopStatusList.add(ca.getCrAprovalStatus());

		}
		// 封装融资银行个数状态集合
		List<String> bankStatusList = new ArrayList<String>();

		String entType = entAcc.getEntType();
		if (entType.equals(EntType.PURCHASER.toString())) {
			ca.setCrApplicantPurId(entAcc.getTid());

			// 待采购商审核状态集合
			bankStatusList.add(CrAprovalStatus.BANK_AUDIT.toString());
			bankStatusList.add(CrAprovalStatus.ICBC_WAIT_CONFIRM_PUR.toString());

		} else {
			ca.setCrApplicantId(entAcc.getTid());
			// 供应商显示待供应商操作的状态集合
			bankStatusList.add(CrAprovalStatus.ICBC_HISTROY_INFO.toString());
			bankStatusList.add(CrAprovalStatus.ICBC_REJECT_PUR.toString());
		}

		ca.setCrProdId(cpeInfo.getTid());

		// 返回bean
		CreditApplicationForm caf = new CreditApplicationForm();
		
		//封装金融状态
		caf.setCreditStatus(entAcc.getCheckStatus());
		// 查询合作银行列表
		List<CreditProductEntity> cpeList = creditProductRepository.findByStatusNot(HelpConstant.Status.delete);
		List<CreditProduct> cpList = new ArrayList<CreditProduct>();
		for (CreditProductEntity cpe : cpeList) {
			CreditProduct cp = new CreditProduct();
			Integer bankCooCount = creditApplicationRepository.findCooBankCount(HelpConstant.Status.delete, bankStatusList, ca.getCrApplicantPurId(), ca.getCrApplicantId(),
					cpe.getTid());
			BeanUtils.copyProperties(cpe, cp);
			cp.setCooperativeCount(bankCooCount);
			cpList.add(cp);
		}

		// 封装排序和分页bean
		Order order = new Order(Direction.DESC, "create_time");
		List<Order> orderList = new ArrayList<Order>();
		orderList.add(order);
		Sort sort = new Sort(orderList);
		Pageable pageSort = new PageRequest(ca.getNextPage(), ca.getPageSize(), sort);

		List<Object[]> objList = creditApplicationRepository.findBusList(HelpConstant.Status.delete, ca.getEnterpriseSupName(), ca.getEnterprisePurName(), coopStatusList,
				ca.getCrApplicantPurId(), ca.getCrApplicantId(), ca.getCrProdId(), pageSort);

		Integer busCount = creditApplicationRepository.findBusCount(HelpConstant.Status.delete, ca.getEnterpriseSupName(), ca.getEnterprisePurName(), coopStatusList,
				ca.getCrApplicantPurId(), ca.getCrApplicantId(), ca.getCrProdId());

		List<CreditApplication> getcoopBusListBy = new ArrayList<CreditApplication>();
		if (CollectionUtils.isNotEmpty(objList)) {
			for (Object[] obj : objList) {
				CreditApplication capp = new CreditApplication();
				capp.setEnterpriseSupName(SqlResultUtil.getSqlResultString(obj[0]));
				capp.setLinkPerson(SqlResultUtil.getSqlResultString(obj[1]));
				capp.setLinkTel(SqlResultUtil.getSqlResultString(obj[2]));
				capp.setCrApplyTime(SqlResultUtil.getSqlResultDate2(SqlResultUtil.getSqlResultString(obj[3])));
				capp.setBusBankName(SqlResultUtil.getSqlResultString(obj[4]));
				capp.setCrAprovalStatus(SqlResultUtil.getSqlResultString(obj[6]));
				capp.setCrApplicantId(SqlResultUtil.getSqlResultLong(obj[9]));
				capp.setCrApplicantPurId(SqlResultUtil.getSqlResultLong(obj[10]));
				capp.setTid(SqlResultUtil.getSqlResultLong(obj[11]));
				capp.setEnterprisePurName(SqlResultUtil.getSqlResultString(obj[12]));
				capp.setTermOfValidity(SqlResultUtil.getSqlResultInteger(obj[13]));
				capp.setCrProdEndTime(SqlResultUtil.getSqlResultDate3(SqlResultUtil.getSqlResultString(obj[14])));
				capp.setApplyAmt(SqlResultUtil.getSqlResultBigDecimal(obj[15]));
				capp.setAmountOfFinancing(SqlResultUtil.getSqlResultBigDecimal(obj[16]));
				capp.setCrProdType(SqlResultUtil.getSqlResultString(obj[17]));
				capp.setRejectRemark(SqlResultUtil.getSqlResultString(obj[18]));
				capp.setThisYearsGrowthRate(SqlResultUtil.getSqlResultBigDecimal(obj[19]));
				getcoopBusListBy.add(capp);
			}
		}

		MyPage<CreditApplication> myPage = new MyPage<CreditApplication>(ca.getNextPage(), ca.getPageSize(), getcoopBusListBy, busCount);
		caf.setCreditApplicationPage(myPage);
		caf.setCreditProductList(cpList);
		// 查询工行筑保通是否开通
		CreditProductEntity icbcCpe = creditProductRepository.findByCrProdTypeAndStatusNot(CrProdType.ICBC_R_E_J.toString(), HelpConstant.Status.delete);
		EntCrProdEntity ecpe = entCrProdEntityRepository.findByEntId(ca.getEnterpriseId(), ca.getEntType(), icbcCpe.getTid(), ZhuCaiProdType.ZHU_CAI_B_TONG.toString());
		if (ecpe != null && ecpe.getEnCrStatus().equals(EnCrStatus.PASS.toString())) {
			caf.setFinanceIcbcProdBol(true);
		} else {
			caf.setFinanceIcbcProdBol(false);
		}
		// 查询工行筑保通是否开通
		CreditProductEntity ccbCpe = creditProductRepository.findByCrProdTypeAndStatusNot(CrProdType.E_POINT.toString(), HelpConstant.Status.delete);
		EntCrProdEntity ccbEcpe = entCrProdEntityRepository.findByEntId(ca.getEnterpriseId(), ca.getEntType(), ccbCpe.getTid(), ZhuCaiProdType.ZHU_CAI_B_TONG.toString());
		if (ccbEcpe != null && ccbEcpe.getEnCrStatus().equals(EnCrStatus.PASS.toString())) {
			caf.setFinanceCcbProdBol(true);
		} else {
			caf.setFinanceCcbProdBol(false);
		}
		return caf;
	}

	/**
	 * 核心企业推荐供应商
	 * 
	 * @version 2018年8月13日
	 * @param creditApplication
	 * @return
	 */
	@Override
	public CreditApplication recommendEnterprise(CreditApplication creditApplication) {
		logger.info("### 工商银行核心企业推荐供应商 start ca = {}", creditApplication.toString());

		Long purEntId = creditApplication.getPurEnterpriseId();
		Long supEntId = creditApplication.getSupEnterpriseId();
		
		EntAccountEntity purAcc = entAccountRepository.findByStatusNotAndEnterpriseIdAndEntType(HelpConstant.Status.delete, purEntId, EntType.PURCHASER.toString());
		if (purAcc == null) {
			
			logger.error("### 工商银行核心企业推荐供应商失败 purEntId={},核心企业还未入驻金融", purEntId);
			throw new RuntimeException("推荐供应商失败！");
		}
		try {
			EntAccountEntity supAcc = entAccountRepository.findByStatusNotAndEnterpriseIdAndEntType(HelpConstant.Status.delete, supEntId, EntType.SUPPLIER.toString());


			CreditProductEntity cpe = creditProductRepository.findByCrProdTypeAndStatusNot(CrProdType.ICBC_R_E_J.toString(), HelpConstant.Status.delete);
			if (cpe == null) {
				logger.error("### 查询工商银行机构信息失败 ICBC_R_E_J");
				throw new RuntimeException("查询工商银行机构信息失败！");
			}

			CreditApplicationEntity cae = creditApplicationRepository.findBySupEntId(cpe.getTid(), supEntId, purAcc.getTid());

			if (cae == null) {
				cae = new CreditApplicationEntity();

				// 由于工行没有报名编号但为了数据一致性，给工行申请加上
				SimpleDateFormat sf = new SimpleDateFormat("yyyyMMddHHmmss");
				String appNum = "ICBC" + sf.format(new Date());
				cae.setAppNum(appNum);
				cae.setApplicantEnterpriseId(supEntId);
				cae.setApplicantName(creditApplication.getApplicantName());
				cae.setApplicantPhone(creditApplication.getApplicantPhone());
				cae.setCrApplicantPurId(purAcc.getTid());
//				cae.setCrAprovalStatus(CrAprovalStatus.ICBC_APPROVE_FIRST.toString());
				cae.setCrProdstatus(CrProdstatus.WAIT_APPROVAL.toString());
				cae.setCrProdId(cpe.getTid());
				cae.setCooOrgnNum(purAcc.getOrgNum());
				cae.setAppOrgnNum(creditApplication.getAppOrgnNum());
				cae.setApplicantEnterpriseName(creditApplication.getApplicantEnterpriseName());
				// 由于工商银行推荐供应商时供应商可能没入驻金融，当没有入驻金融时给供应商的金融id暂时给 999999999
				cae.setCrApplicantId(supAcc == null ? Long.valueOf(999999999) : supAcc.getTid());
				cae.setCrApplyTime(new Date());
				cae.setApplicantMobile(creditApplication.getApplicantPhone());
				creditApplicationRepository.save(cae);

				// 新增操作记录
				OperRecordEntity operRecord = new OperRecordEntity();
//				operRecord.setBizKey(CrAprovalStatus.ICBC_APPROVE_FIRST.toString());
				operRecord.setModifyDescription("工商银行核心企业推荐供应商");
				operRecord.setOperator(creditApplication.getUserId());
				operRecord.setOperTime(new Date());
				operRecord.setOperType(OperType.PUR_COOP_SUP.toString());
				operRecord.setOutId(cae.getTid());
//				operRecord.setResult(CrAprovalStatus.ICBC_APPROVE_FIRST.toString());
				operRecord.setReview("工商银行核心企业推荐供应商");
				operRecordRepository.save(operRecord);
			} else if (cae.getCrAprovalStatus().equals(CrAprovalStatus.ICBC_STOP_PUR.toString()) || cae.getCrAprovalStatus().equals("ICBC_FIRST_REJECT")) {
				// 工行模式下在核心企业终止下和银行初审驳回，重新推荐供应商
				cae.setApplicantName(creditApplication.getApplicantName());
				cae.setApplicantPhone(creditApplication.getApplicantPhone());
				cae.setApplicantEnterpriseName(creditApplication.getApplicantEnterpriseName());
				Integer coo = creditApplicationRepository.updateLinkInfoApprove(cae.getTid(), creditApplication.getApplicantName(), creditApplication.getApplicantPhone(),
						cae.getApplicantEnterpriseName());
				if (coo != 1) {
					logger.error("### 工商银行核心企业推荐供应商失败 更新返回coo = {}", coo);
					throw new RuntimeException("核心企业推荐供应商 更新联系人失败");
				}
			} else {
				BeanUtils.copyProperties(cae, creditApplication);
				return creditApplication;
			}

			BeanUtils.copyProperties(cae, creditApplication);

			if (supAcc != null) {
				// 新增供应商筑保通信息
				EntCrProdEntity ecpe = entCrProdEntityRepository.findByEnAccId(supAcc.getTid(), cae.getCrProdId(), EntType.SUPPLIER.toString(),
						ZhuCaiProdType.ZHU_CAI_B_TONG.toString());
				if (ecpe == null) {
					ecpe = new EntCrProdEntity();
					ecpe.setApplyTime(new Date());
					ecpe.setCrProdRate(BigDecimal.ONE);
					ecpe.setCrProdRateStr("基准利率");
					ecpe.setCrPrTypeId(cae.getCrProdId());
					ecpe.setEcpStatus(0);
					ecpe.setEnAccId(supAcc.getTid());
					ecpe.setEnCrStatus(EnCrStatus.APPROVALING.toString());
					ecpe.setEnterpriseId(supAcc.getEnterpriseId());
					ecpe.setEntType(EntType.SUPPLIER.toString());
					ecpe.setModifyDescription("核心企业推荐供应商时生成");
					ecpe.setOrgnNum(supAcc.getOrgNum());
					ecpe.setZhucaiProdType(ZhuCaiProdType.ZHU_CAI_B_TONG.toString());
					entCrProdEntityRepository.save(ecpe);
				}
			}
			// 生成统一excel名称
			SimpleDateFormat sf = new SimpleDateFormat("yyyyMMddHHmmss");
			String excelName = creditApplication.getApplicantEnterpriseName() + "_客户准入申请_" + sf.format(new Date()) + ".xlsx";
			creditApplication.setExcelName(excelName);

			// 导出excel
			List<CreditApplication> crList = new ArrayList<CreditApplication>();
			creditApplication.setCooOrgnNum(purAcc.getOrgNum());
			crList.add(creditApplication);
			excelExportUtil.createEnteriseInfoExcel(crList);
			// 发送邮件
			emailServiceUtil.sendEnteriseInfoEmail(creditApplication);
		} catch (Exception e) {
			logger.error("### 核心企业推荐供应商异常", e);
			emailINotificationService.notification("### 核心企业:"+purAcc.getEnterpriseName()+"推荐供应商异常 e="+e);
			throw new RuntimeException("核心企业:"+purAcc.getEnterpriseName()+"推荐供应商异常");
		}
		
		return creditApplication;
	}

	/**
	 * 工商银行 处理 历史交易记录
	 * 
	 * @version 2018年8月14日
	 * @param ca
	 * @return
	 */
	@Override
	public CreditApplication approveHistroyInfo(CreditApplication ca) {
		
		logger.info("### 工商银行 处理 历史交易记录 start ca={}", ca.toString());
		try {
			// 如果是采购商就是审核供应商
			if (ca.getEntType().equals(EntType.PURCHASER.toString())) {
				approveHistroyInfoPur(ca);
			}else if(ca.getEntType().equals(EntType.SUPPLIER.toString())){
				approveHistroyInfoSup(ca);
			}
			
			ca.setReturnStatus("OK");
		} catch (Exception e) {
			logger.error("### 工行处理历史交易记录异常 资质申请记录caId={}，err={}", ca.getTid(),e);
			emailINotificationService.notification("### 工行处理历史交易记录异常tid="+ca.getTid()+"err="+e);
			String problem = "工商银行 处理 历史交易记录异常 资质申请td=" + ca.getTid();
			problemSericeImpl.setProblem(problem, "ICBC_APROVE_SUP");
			throw new RuntimeException("处理 历史交易记录异常");
		}
		return ca;
	}
	
	private void approveHistroyInfoSup(CreditApplication ca){
		CreditApplicationEntity cae = new CreditApplicationEntity();
		
		// 查询供应商金融信息
		EntAccountEntity entAcc = entAccountRepository.findByStatusNotAndEnterpriseIdAndEntType(HelpConstant.Status.delete, ca.getApplicantEnterpriseId(),
				EntType.SUPPLIER.toString());
		if(entAcc == null){
			logger.error("### 供应商申请工行异常，获取供应商融资信息异常,supEntId = {}",ca.getApplicantEnterpriseId());
			throw new RuntimeException("供应商申请工行异常，获取供应商融资信息异常！");
		}
		EntAccountEntity purAcc = entAccountRepository.findByTid(ca.getCrApplicantPurId());
		if(purAcc == null){
			logger.error("### 供应商申请工行异常，获取采购商融资信息异常,purEntId = {}",ca.getCrApplicantPurId());
			throw new RuntimeException("供应商申请工行异常，获取采购商融资信息异常！");
		}
		if(ca.getTid() != null){
			 cae = creditApplicationRepository.findOne(ca.getTid());
			 ca.setRejectRemark(null);
			 Integer coo = creditApplicationRepository.updateHistroyInfo(ca.getHistoryTransactionYears(), ca.getHistoryDisputeCount(), ca.getHistoryDebtRate(), ca.getReturnRate(),
						ca.getThreeYearsSupply(), ca.getThreeYearsReceivable(), ca.getTwoYearsSupply(), ca.getTwoYearsReceivable(), ca.getOneYearsSupply(), ca.getOneYearsReceivable(),
						ca.getThisYearsGrowthRate(), CrAprovalStatus.ICBC_WAIT_CONFIRM_PUR.toString(), ca.getRejectRemark(), cae.getCrApplicantId(), ca.getTid(),ca.getApplicantMobile(),ca.getApplicantName());
			 
			 if(coo != 1){
				 logger.error("### 核心企业（pur={}）审核工行历史记录供应商sup={},更新数据返回异常 coo={}",purAcc.getEnterpriseName(),entAcc.getEnterpriseName(),coo);
				 throw new RuntimeException("核心企业审核供应商工行历史记录异常！");
			 }
		}else{
			CreditProductEntity cpe = creditProductRepository.findByCrProdTypeAndStatusNot(CrProdType.ICBC_R_E_J.toString(), HelpConstant.Status.delete);
			if (cpe == null) {
				logger.error("### 查询工商银行机构信息失败 ICBC_R_E_J");
				throw new RuntimeException("查询工商银行机构信息失败！");
			}
			//新增融资申请记录
			// 由于工行没有报名编号但为了数据一致性，给工行申请加上
			SimpleDateFormat sf = new SimpleDateFormat("yyyyMMddHHmmss");
			String appNum = "ICBC" + sf.format(new Date());
			cae.setAppNum(appNum);
			//供应商企业信息部分
			cae.setApplicantEnterpriseId(entAcc.getEnterpriseId());
			cae.setApplicantEnterpriseName(entAcc.getEnterpriseName());
			cae.setApplicantMobile(ca.getApplicantMobile());
			cae.setApplicantName(ca.getApplicantName());
			cae.setAppOrgnNum(entAcc.getOrgNum());
			cae.setCrApplicantId(entAcc.getTid());
			//采购商信息部分
			cae.setCrApplicantPurId(purAcc.getTid());
			cae.setCooOrgnNum(purAcc.getOrgNum());
			//业务状态部分
			cae.setCrAprovalStatus(CrAprovalStatus.ICBC_WAIT_CONFIRM_PUR.toString());
			cae.setCrProdstatus(CrProdstatus.WAIT_APPROVAL.toString());
			cae.setCrProdId(cpe.getTid());
			//历史交易数据部分
			cae.setHistoryTransactionYears(ca.getHistoryTransactionYears());
			cae.setHistoryDisputeCount(ca.getHistoryDisputeCount());
			cae.setHistoryDebtRate(ca.getHistoryDebtRate());
			cae.setReturnRate(ca.getReturnRate());
			cae.setThreeYearsSupply(ca.getThreeYearsSupply());
			cae.setThreeYearsReceivable(ca.getThreeYearsReceivable());
			cae.setTwoYearsSupply(ca.getTwoYearsSupply());
			cae.setTwoYearsReceivable(ca.getTwoYearsReceivable());
			cae.setOneYearsSupply(ca.getOneYearsSupply());
			cae.setOneYearsReceivable(ca.getOneYearsReceivable());
			cae.setThisYearsGrowthRate(ca.getThisYearsGrowthRate());
			
			cae.setCrApplyTime(new Date());
			
			creditApplicationRepository.save(cae);

			// 新增供应商筑保通信息
			EntCrProdEntity ecpe = entCrProdEntityRepository.findByEnAccId(entAcc.getTid(), cpe.getTid(), EntType.SUPPLIER.toString(),
					ZhuCaiProdType.ZHU_CAI_B_TONG.toString());
			
			if (ecpe == null) {
				ecpe = new EntCrProdEntity();
				ecpe.setApplyTime(new Date());
				ecpe.setCrProdRate(BigDecimal.ONE);
				ecpe.setCrProdRateStr("基准利率");
				ecpe.setCrPrTypeId(cae.getCrProdId());
				ecpe.setEcpStatus(0);
				ecpe.setEnAccId(entAcc.getTid());
				ecpe.setEnCrStatus(EnCrStatus.APPROVALING.toString());
				ecpe.setEnterpriseId(entAcc.getEnterpriseId());
				ecpe.setEntType(EntType.SUPPLIER.toString());
				ecpe.setModifyDescription("供应商历史记录提交时生成筑保通信息");
				ecpe.setOrgnNum(entAcc.getOrgNum());
				ecpe.setZhucaiProdType(ZhuCaiProdType.ZHU_CAI_B_TONG.toString());
				entCrProdEntityRepository.save(ecpe);
			}
			try {
				// 新增操作记录
				OperRecordEntity operRecord = new OperRecordEntity();
				operRecord.setBizKey(CrAprovalStatus.ICBC_WAIT_CONFIRM_PUR.toString());
				operRecord.setModifyDescription("供应商申请工行");
				operRecord.setOperator(ca.getUserId());
				operRecord.setOperTime(new Date());
				operRecord.setOperType(OperType.PUR_COOP_SUP.toString());
				operRecord.setOutId(cae.getTid());
				operRecord.setResult(CrAprovalStatus.ICBC_WAIT_CONFIRM_PUR.toString());
				operRecord.setReview("工商银行核心企业推荐供应商");
				operRecordRepository.save(operRecord);
			} catch (Exception e) {
				logger.error("供应商申请工行时新增操作记录失败 err={}", e);
			}
		}
	}
	private void approveHistroyInfoPur(CreditApplication ca){
		
		CreditApplicationEntity cae = creditApplicationRepository.findOne(ca.getTid());
		
		// 查询供应商金融信息
		EntAccountEntity entAcc = entAccountRepository.findByStatusNotAndEnterpriseIdAndEntType(HelpConstant.Status.delete, cae.getApplicantEnterpriseId(),
				EntType.SUPPLIER.toString());
		EntAccountEntity purAcc = entAccountRepository.findByTid(cae.getCrApplicantPurId());
		
		// 添加审核操作记录
		OperRecordEntity ore = new OperRecordEntity();
		ore.setOutId(ca.getTid());
		ore.setBizType(OperType.PUR_APP_SUP.toString());
		ore.setOperator(ca.getUserId());
		ore.setOperatorName(ca.getUserName());
		ore.setOperType(OperType.PUR_APP_SUP.toString());
		ore.setOperTime(new Date());
		/**
		 * 工商银行业务部分数据
		 */
		ore.setHistoryTransactionYears(cae.getHistoryTransactionYears());
		ore.setHistoryDisputeCount(cae.getHistoryDisputeCount());
		ore.setHistoryDebtRate(cae.getHistoryDebtRate());
		ore.setReturnRate(cae.getReturnRate());
		ore.setThreeYearsSupply(cae.getThreeYearsSupply());
		ore.setThreeYearsReceivable(cae.getThreeYearsReceivable());
		ore.setTwoYearsSupply(cae.getTwoYearsSupply());
		ore.setTwoYearsReceivable(cae.getTwoYearsReceivable());
		ore.setOneYearsSupply(cae.getOneYearsSupply());
		ore.setOneYearsReceivable(cae.getOneYearsReceivable());
		ore.setThisYearsGrowthRate(cae.getThisYearsGrowthRate());
		ore.setReview(ca.getRejectRemark());
		
		Integer coo = 0;
		
		Integer approveStatus = ca.getApproveStatus();
		if (approveStatus == 1) {
			ore.setBizKey("ICBC_APPROVE_TWO");
			ore.setResult("采购商审核通过");
			logger.info("### 采购商审核通过供应商 tid={},approveStatus={}", cae.getTid(), approveStatus);
			coo = creditApplicationRepository.updatePurPass(ca.getTid());
			List<Object[]> rs = creditApplicationRepository.findEntInfoById(ca.getTid());
			if (CollectionUtils.isNotEmpty(rs)) {
				for (Object[] obj : rs) {
					ca.setEnterpriseSupName(SqlResultUtil.getSqlResultString(obj[0]));
					ca.setApplicantEnterpriseName(SqlResultUtil.getSqlResultString(obj[0]));
					ca.setEnterprisePurName(SqlResultUtil.getSqlResultString(obj[3]));
				}
			}
			// 生成统一excel名称
			SimpleDateFormat sf = new SimpleDateFormat("yyyyMMddHHmmss");
			String excelName = cae.getApplicantEnterpriseName() + "_历史交易数据_" + sf.format(new Date()) + ".xlsx";
			ca.setExcelName(excelName);
			List<CreditApplication> excelList = new ArrayList<CreditApplication>();
			ca.setAppOrgnNum(cae.getAppOrgnNum());
			ca.setPurUnifyCert(purAcc.getUnityOrgNum());
			ca.setSupUnifyCert(entAcc.getUnityOrgNum());
			ca.setCooOrgnNum(cae.getCooOrgnNum());
			excelList.add(ca);
			
			excelExportUtil.exportHistroynfoExcel(excelList);
			
			emailServiceUtil.sendHistroyInfoEmail(ca);
		} else if (approveStatus == 2) {
			ore.setBizKey("ICBC_REJECT_PUR");
			ore.setResult("采购商审核驳回");
			
			logger.info("### 采购商审核驳回供应商 tid={},approveStatus={}", ca.getTid(), approveStatus);
			coo = creditApplicationRepository.updatePurReject(ca.getTid(), ca.getRejectRemark());
		} else if (approveStatus == 3) {
			ore.setBizKey("ICBC_REJECT_PUR");
			ore.setResult("采购商审核终止");
			
			logger.info("### 采购商审核终止供应商 tid={},approveStatus={}", ca.getTid(), approveStatus);
			coo = creditApplicationRepository.updatePurStop(ca.getTid(), ca.getRejectRemark());
		}
		
		if (coo != 1) {
			ca.setReturnStatus("FAIL");
			ca.setReturnMessage("数据更新异常,请刷新后重试");
			logger.error("### 工商银行 处理 历史交易记录 发生异常 查询资质申请记录失败 失败tid={}", ca.getTid());
			throw new RuntimeException("数据更新异常,请刷新后重试");
		}
		operRecordRepository.save(ore);
		
		// 更新融资申请记录的最近操作记录id
		Integer count = creditApplicationRepository.updateOperId(ca.getTid(), ore.getTid());
		if (count != 1) {
			logger.warn("### 工商银行 处理 历史交易记录 时 更新最近操作记录异常 操作记录operId={},资质申请记录caId={}", ore.getTid(), ca.getTid());
			String problem = "工商银行 处理 历史交易记录 时 更新最近操作记录异常 操作记录id=" + ore.getTid() + "资质申请记录id=" + ca.getTid();
			problemSericeImpl.setProblem(problem, "ICBC_APROVE_SUP");
		}
	}
	
	@Override
	public EntCrProd getZhuBaoTongInfo(Long entId, String entType, Long bankTid) {
		logger.info("### 根据企业id和企业类型和融资机构id查询筑保通信息 entId = {}，entType={},bankTid", entId,entType,bankTid);
		EntCrProdEntity ecpe = entCrProdEntityRepository.findCrProdInfo(HelpConstant.Status.delete, entId, entType, bankTid);
		if (ecpe != null) {
			EntCrProd ecp = new EntCrProd();
			BeanUtils.copyProperties(ecpe,ecp);
			return ecp;
		}
		return null;
	}

	@Override
	public CreditApplication findApplicantInfoByPurId(Long purAccId, Long enterpriseId,String bankType) {
		logger.info("### 查询合作企业start purAccId={},enterpriseId = {}", purAccId,enterpriseId);
		CreditApplication ca = new CreditApplication();
		// 查询供应商金融信息
		EntAccountEntity supAcc = entAccountRepository.findByStatusNotAndEnterpriseIdAndEntType(HelpConstant.Status.delete, enterpriseId,
				EntType.SUPPLIER.toString());
		List<CreditApplicationEntity> rsList = creditApplicationRepository.findByPurAccIdAndSupAccId(purAccId,supAcc.getTid(),bankType);
		if(CollectionUtils.isEmpty(rsList)){
			return ca;
		}
		if(rsList.size() == 1){
			CreditApplicationEntity creditApplicationEntity = rsList.get(0);
			BeanUtils.copyProperties(creditApplicationEntity, ca);
		}
		if(rsList.size() > 1){
			for (CreditApplicationEntity creditApplicationEntity : rsList) {
				if(!creditApplicationEntity.getCrAprovalStatus().equals(CrAprovalStatus.BANK_SUCCESS.toString())){
					BeanUtils.copyProperties(creditApplicationEntity, ca);
					break;
				}
			}
		}
		
		return ca;
	}
}
